/*******************************************************************************
 * Package: com.hngtrust.iir.risk.service.impl
 * Type:    RiskCompServiceImpl
 * Date:    2021/5/8 16:08
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.risk.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hngtrust.clickhouse.news.dto.ListRiskNewsReqDTO;
import com.hngtrust.clickhouse.news.dto.QuerySentimentByNewsIdDTO;
import com.hngtrust.clickhouse.news.dto.RiskPageNewsReqVO;
import com.hngtrust.clickhouse.news.entity.AppNews;
import com.hngtrust.clickhouse.news.entity.AppNewsSentiment;
import com.hngtrust.clickhouse.news.service.AppNewsSentimentService;
import com.hngtrust.clickhouse.news.service.AppNewsService;
import com.hngtrust.framework.page.PageResult;
import com.hngtrust.framework.page.service.PageService;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.base.entity.Dict;
import com.hngtrust.iir.base.service.DictService;
import com.hngtrust.iir.company.dto.ListRiskRespDTO;
import com.hngtrust.iir.company.entity.CompDept;
import com.hngtrust.iir.company.service.CompDeptService;
import com.hngtrust.iir.company.service.CompRiskService;
import com.hngtrust.iir.company.service.CompanyService;
import com.hngtrust.iir.constant.Constant;
import com.hngtrust.iir.dto.ReqDTO;
import com.hngtrust.iir.elk.exception.ElkErrorType;
import com.hngtrust.iir.elk.exception.ElkException;
import com.hngtrust.iir.exception.IirErrorType;
import com.hngtrust.iir.exception.IirException;
import com.hngtrust.iir.homepage.controller.dto.UserMessageReqDTO;
import com.hngtrust.iir.homepage.controller.dto.UserMessageRespDTO;
import com.hngtrust.iir.news.controller.dto.ListNewsRespVO;
import com.hngtrust.iir.risk.controller.dto.HomePageNewsRespVO;
import com.hngtrust.iir.risk.controller.dto.HomePageNewsTrendVO;
import com.hngtrust.iir.risk.controller.dto.HomePageRiskReqVO;
import com.hngtrust.iir.risk.controller.dto.HomePageRiskRespVO;
import com.hngtrust.iir.risk.controller.dto.HomePageTrendVO;
import com.hngtrust.iir.risk.controller.dto.ListRiskNewsReqVO;
import com.hngtrust.iir.risk.controller.dto.QueryCompAssociateRiskReqVO;
import com.hngtrust.iir.risk.controller.dto.QueryCompNewsReqVO;
import com.hngtrust.iir.risk.controller.dto.QueryCompRiskReqVO;
import com.hngtrust.iir.risk.controller.dto.RiskHomePageLevelVO;
import com.hngtrust.iir.risk.controller.dto.RiskHomePageReqVO;
import com.hngtrust.iir.risk.controller.dto.RiskTrendVO;
import com.hngtrust.iir.risk.dto.QueryByRiskTypeDTO;
import com.hngtrust.iir.risk.dto.QueryByRiskTypeRespDTO;
import com.hngtrust.iir.risk.dto.QueryCompAssociateDTO;
import com.hngtrust.iir.risk.dto.QueryCompAssociateReqDTO;
import com.hngtrust.iir.risk.dto.RiskDTO;
import com.hngtrust.iir.risk.dto.RiskTimeDTO;
import com.hngtrust.iir.risk.dto.RiskTypeDTO;
import com.hngtrust.iir.risk.entity.RiskMonitor;
import com.hngtrust.iir.risk.entity.RiskSchemeConfig;
import com.hngtrust.iir.risk.service.RiskCompService;
import com.hngtrust.iir.risk.service.RiskMonitorService;
import com.hngtrust.iir.risk.service.RiskSchemeConfigService;
import com.hngtrust.iir.risk.service.RiskTypeService;
import com.hngtrust.iir.user.entity.TagRel;
import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.user.service.SelfTagService;
import com.hngtrust.iir.user.service.TagRelService;
import com.hngtrust.iir.util.DateUtils;
import com.hngtrust.iir.util.HtmlUtils;
import com.tiger.util.MyHttpClient;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 公司风险
 *
 * @author Keqiwei
 * @date 2021/5/8 16:08
 */
@Service
@Slf4j
public class RiskCompServiceImpl implements RiskCompService {
    
    @Autowired
    private RiskTypeService riskTypeService;
    
    
    @Autowired
    private AppNewsSentimentService appNewsSentimentService;
    
    @Autowired
    private RiskSchemeConfigService configService;
    
    @Autowired
    private TagRelService tagRelService;
    
    @Autowired
    private SelfTagService selfTagService;
    
    @Autowired
    private DictService dictService;
    
    @Autowired
    private CompanyService companyService;
    
    @Autowired
    private PageService pageService;
    
    @Autowired
    private RiskMonitorService monitorService;
    
    @Autowired
    private CompRiskService compRiskService;
    
    @Autowired
    private AppNewsService newsService;
    
    @Value("${ai.department-query.url}")
    private String url;
    
    @Value("${tiger.minio.out.address}")
    private String minioAddress;
    
    @Autowired
    private CompDeptService compDeptService;
    
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    /**
     * 根据风险类型查询
     * @param dto
     * @return
     */
    @Override
    public PageResult<QueryByRiskTypeRespDTO> queryListByRiskType(ReqDTO<QueryCompRiskReqVO> dto){
        QueryByRiskTypeDTO query = new QueryByRiskTypeDTO();
        BeanUtils.copyProperties(dto.getContent(),query);
        String[] time = time(dto.getContent().getTimeType(), dto.getContent().getBeginDate(), dto.getContent().getEndDate());
        query.setBeginTime(time[0]);
        query.setEndTime(time[1]);
        PageResult<QueryByRiskTypeRespDTO> page = pageService
                .page(dto.getPageParam(), () -> riskTypeService.queryListByRiskType(query));
        Map<String, Dict> riskClass = dictService.queryDict("RISK_CLASS");
        Map<String, Dict> riskLevel = dictService.queryDict("RISK_LEVEL");
        Map<String, Dict> riskTag = dictService.queryDict("RISK_TAG");
        page.getRows().forEach(q->{
            if (q.getRiskClassCode() != null){
                q.setRiskClass(dictService.queryDictByCode(riskClass,q.getRiskClassCode().toString()).getBusiName());
            }
            
            if(q.getRiskLevelCode() != null){
                q.setRiskLevel(dictService.queryDictByCode(riskLevel,q.getRiskLevelCode().toString()).getBusiName());
            }
            
            if (q.getRiskTagCode() != null){
                q.setRiskTag(dictService.queryDictByCode(riskTag,q.getRiskTagCode().toString()).getBusiName());
            }
            
            if (null != q.getRiskContent()){
                q.setRiskContent(q.getRiskContent().replaceAll("null","-"));
            }
            
        });
        return page;
    }
    
    
    /**
     * 查询关联公司风险
     */
    @Override
    public List<QueryCompAssociateDTO> queryCompAssociateRisk(ReqDTO<QueryCompAssociateRiskReqVO> dto){
        String[] time = time(dto.getContent().getTimeType(), dto.getContent().getBeginDate(), dto.getContent().getEndDate());
        List<UserMessageRespDTO> names = new ArrayList<>();
        UserMessageReqDTO bo = new UserMessageReqDTO();
        MyHttpClient myHttpClient = new MyHttpClient();
        UserMessageReqDTO.Comp comp = new UserMessageReqDTO.Comp();
        comp.setCompanyName(dto.getContent().getCompName());
        bo.setCompanyList(Collections.singletonList(comp));
        bo.setHopCount(dto.getContent().getConnection());
        String json;
        try{
            json = myHttpClient.postJson(url, bo);
        }catch (Exception e){
            throw new IirException(IirErrorType.QUERY_COMP_ASSOCIATE_RISK,e.toString());
        }
        
        List<UserMessageRespDTO>  list = new ArrayList<>();
        try {
            JsonNode jsonNode = OBJECT_MAPPER.readTree(json);
            JsonNode dataJson = jsonNode.get("data");
            log.error(dto.getContent().getCompName()+"关联关系"+dataJson.toString());
            
            list = OBJECT_MAPPER.readValue(dataJson.toString(),
                    OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, UserMessageRespDTO.class));
        }catch (Exception e){
            log.error("获取该公司关联公司失败",dto.getContent().getCompId());
            throw new IirException(IirErrorType.JSON_CONVERSION,e.toString());
        }
        
        if (Constant.COMP_CONNECTION_ONE.equals(dto.getContent().getConnection())) {
    
            List<UserMessageRespDTO> dtos = list.stream().filter(l -> {
                if (Constant.COMP_CONNECTION_ONE.equals(l.getHopCount())) {
                    return true;
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
    
            if (dto.getContent().getAssociate().isEmpty()){
                names.addAll(dtos);
            }else {
                for (String s : dto.getContent().getAssociate()){
                    names.addAll(dtos.stream().filter(l -> {
                        if (l.getRelationShip().indexOf(s) != -1) {
                            return true;
                        } else {
                            return false;
                        }
                    }).collect(Collectors.toList()));
                }
            }
        
        
        }else if (Constant.COMP_CONNECTION_TWO.equals(dto.getContent().getConnection())){
            List<UserMessageRespDTO> dtos = list.stream().filter(l -> {
                if (Constant.COMP_CONNECTION_TWO.equals(l.getHopCount())) {
                    return true;
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
            if (dto.getContent().getAssociate().isEmpty()){
                names.addAll(dtos);
            }else {
                for (String s : dto.getContent().getAssociate()){
                    names.addAll(dtos.stream().filter(l -> {
                        if (l.getRelationShip().indexOf(s) != -1) {
                            return true;
                        } else {
                            return false;
                        }
                    }).collect(Collectors.toList()));
                }
            }
        
        }else if (Constant.COMP_CONNECTION_THREE.equals(dto.getContent().getConnection())){
    
            List<UserMessageRespDTO> dtos = list.stream().filter(l -> {
                if (Constant.COMP_CONNECTION_THREE.equals(l.getHopCount())) {
                    return true;
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
            if (dto.getContent().getAssociate().isEmpty()){
                names.addAll(dtos);
            }else {
                for (String s : dto.getContent().getAssociate()){
                    names.addAll(dtos.stream().filter(l -> {
                        if (l.getRelationShip().indexOf(s) != -1) {
                            return true;
                        } else {
                            return false;
                        }
                    }).collect(Collectors.toList()));
                }
            }
        
        }
        QueryCompAssociateReqDTO reqDTO = new QueryCompAssociateReqDTO();
        reqDTO.setBeginTime(time[0]);
        reqDTO.setEndTime(time[1]);
        reqDTO.setCompNames(names.stream().map(n->n.getCompanyName()).collect(Collectors.toList()));
        BeanUtils.copyProperties(dto.getContent(),reqDTO);
        List<QueryCompAssociateDTO> queryCompAssociateDTOS = riskTypeService.queryCompAssociateRisk(reqDTO);
        List<QueryCompAssociateDTO> dtoList = new ArrayList<>();
       

    
        Map<String, Dict> riskClass = dictService.queryDict("RISK_CLASS");
        Map<String, Dict> riskLevel = dictService.queryDict("RISK_LEVEL");
        Map<String, Dict> riskTag = dictService.queryDict("RISK_TAG");
        Integer count = 0;
        int start = (dto.getPageParam().getPageNum()-1)*dto.getPageParam().getPageSize();
        for (QueryCompAssociateDTO queryCompAssociateDTO : queryCompAssociateDTOS) {
            for (UserMessageRespDTO name : names) {
                if (name.getCompanyName().equals(queryCompAssociateDTO.getName())){
                    if (count == start){
                        start=++start;
                        queryCompAssociateDTO.setConnection(dto.getContent().getConnection());
                        queryCompAssociateDTO.setRiskContent(queryCompAssociateDTO.getRiskContent().replaceAll("null",""));
                        queryCompAssociateDTO.setAssociate(name.getRelationShip());
                        queryCompAssociateDTO.setRiskClass(dictService.queryDictByCode(riskClass,queryCompAssociateDTO.getRiskClassCode().toString()).getBusiName());
                        queryCompAssociateDTO.setRiskLevel(dictService.queryDictByCode(riskLevel,queryCompAssociateDTO.getRiskLevelCode().toString()).getBusiName());
                        queryCompAssociateDTO.setRiskTag(dictService.queryDictByCode(riskTag,queryCompAssociateDTO.getRiskTagCode().toString()).getBusiName());
                        dtoList.add(queryCompAssociateDTO);
                    }
                }
            }
            count++;
            if(dtoList.size() == dto.getPageParam().getPageSize()){
                break;
            }
        }
        return dtoList;
    }
    
  
        
    
   
    
    
    /**
     * 查询公司对应新闻
     * @param dto
     * @return
     */
    @Override
    public PageResult<ListNewsRespVO> queryCompNews(ReqDTO<QueryCompNewsReqVO> dto){
        PageResult<ListNewsRespVO> pageResult = new PageResult<>();
        ListRiskNewsReqDTO riskNewsReqDTO = new ListRiskNewsReqDTO();
        riskNewsReqDTO.setCompId(dto.getContent().getCompId().toString());
        riskNewsReqDTO.setSentiments(dto.getContent().getSentiments());
        if ( null != dto.getContent().getEndTime() && !dto.getContent().getEndTime().isEmpty()){
            riskNewsReqDTO.setEnd(dto.getContent().getEndTime()+" 23:59:59");
        }
        riskNewsReqDTO.setStart(dto.getContent().getStartTime());
        PageResult<AppNews> page = pageService.page(dto.getPageParam(), () -> newsService.queryByCompId(riskNewsReqDTO));
        List<ListNewsRespVO> listNewsRespVOS = new ArrayList<>();
        page.getRows().forEach(news->{
            ListNewsRespVO respDTO = new ListNewsRespVO();
            BeanUtils.copyProperties(news,respDTO);
            respDTO.setContent(news.getContent().trim());
            TagRel tagRel = new TagRel();
            tagRel.setDataType(Constant.TAG_DATATYPE_NEWS);
            tagRel.setDataId(news.getId());
            List<TagRel> tagRels = tagRelService.queryList(tagRel);
            
            AppNewsSentiment sentiment = new AppNewsSentiment();
            sentiment.setNewsId(news.getId());
            
    
            
            respDTO.setLabels(tagRels);
            
            List<QuerySentimentByNewsIdDTO> dtos = appNewsSentimentService
                    .querySentimentByNewsId(news.getId());
            if (dtos.size() >10 ){
                int a = 0;
                for (int i = 0; i < dtos.size(); i++) {
                    if (dtos.get(i).getCompName().equals(dto.getContent().getCompName())){
                        a=i;
                        break;
                    }
                }
    
                if (a<=9){
                    dtos = dtos.subList(0,10);
                }else {
                    dtos=     dtos.subList(a-9,a+1);
                }
            }
            respDTO.setCompNames(dtos);
            listNewsRespVOS.add(respDTO);
            if (null != news.getSentiment()){
                if (Constant.SENTIMENT_POSITIVE.equals(news.getSentiment())){
                    respDTO.setSentiment("积极");
                }
                if (Constant.SENTIMENT_NEUTRAL.equals(news.getSentiment())){
                    respDTO.setSentiment("中立");
                }
                if (Constant.SENTIMENT_NEGATIVE.equals(news.getSentiment())){
                    respDTO.setSentiment("消极");
                }
            }
        });
        
        pageResult.setRows(listNewsRespVOS);
        pageResult.setPage(page.getPage());
        return pageResult;
    }
    
    
    
    
    private  String[] time(Integer type,Date begin,Date end){
        //开始日期
        String beginTime = null;
        //结束日期
        String endTime = null;
        
        //查询时间类型 0全部 1当天 2最近7天 3最近一个月 4自定义
        if (Constant.COMP_RISK_TIME_DAY.equals(type)) {
            beginTime = DateUtil.format(DateUtil.date(), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_WEEK.equals(type)) {
            beginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -6), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_MONTH.equals(type)) {
            beginTime = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -1), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_DEFINE.equals(type)) {
            if (null == begin || null == end) {
                throw new ElkException(ElkErrorType.ELK_SEARCH_DATE_NULL);
            }
            beginTime = DateUtil.format(begin, DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(end, 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        }
        String[] time = {beginTime,endTime};
        return time;
    }
    
    @Override
    public List<RiskHomePageLevelVO> riskHomePageLevel(RiskHomePageReqVO vo){
        
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        RiskMonitor monitor = new RiskMonitor();
        if (null != vo.getSchemeId() && !vo.getSchemeId().equals(0L)){
            monitor.setSchemeId(vo.getSchemeId());
        }
        monitor.setCreateUserId(loginUser.getId());
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        List<Long> compIds = monitorService.queryList(monitor).stream().map(m->m.getCompId()).collect(Collectors.toList());
        CompDept dept = new CompDept();
        dept.setDeptId(loginUser.getDeptId());
        compIds.addAll(compDeptService.queryList(dept).stream().map(d->d.getCompId()).collect(Collectors.toList()));
        List<RiskHomePageLevelVO> lists = new ArrayList<>();
        
        if(compIds.isEmpty()){
            return lists;
        }
        String beginTime=null;
        String endTime=null;
        //查询时间类型 0全部 1当天 2最近7天 3最近一个月 4自定义home-page-dynamic
        if (Constant.COMP_RISK_TIME_DAY.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.date(), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN);
        } else if (Constant.COMP_RISK_TIME_WEEK.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -6), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN);
        } else if (Constant.COMP_RISK_TIME_MONTH.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -1), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(),0 ), DatePattern.NORM_DATE_PATTERN);
        } else if (Constant.COMP_RISK_TIME_DEFINE.equals(vo.getTimeType())) {
            if (null == vo.getStartTime() || null == vo.getEndTime()) {
                throw new ElkException(ElkErrorType.ELK_SEARCH_DATE_NULL);
            }
            beginTime = DateUtil.format(vo.getStartTime(), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtils.format(vo.getEndTime(),DateUtils.DATE);
        }
        RiskTimeDTO timeDTO = new RiskTimeDTO();
        timeDTO.setIds(compIds);
        if (vo.getCompId() != null ){
            if(compIds.contains(vo.getCompId())){
                timeDTO.setIds(Collections.singletonList(vo.getCompId()));
            }else {
                return lists;
            }
            
        }
        
        timeDTO.setStartTime(beginTime);
        timeDTO.setEndTime(endTime);
        List<ListRiskRespDTO> compRisks = compRiskService.queryTime(timeDTO);
        
        Map<String,List<ListRiskRespDTO>> map = new HashMap<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        compRisks.forEach(c->{
            String key = format.format(c.getBuildTime());
            List<ListRiskRespDTO> list = map.get(key);
            if (list == null){
                list = new ArrayList<>();
                list.add(c);
                map.put(key,list);
            }else {
                list.add(c);
            }
        });
        
        for (Map.Entry<String, List<ListRiskRespDTO>> entry : map.entrySet()) {
            RiskHomePageLevelVO levelVO = new RiskHomePageLevelVO();
            try {
                levelVO.setTime(format.parse(entry.getKey()));
            }catch (Exception e){
                e.printStackTrace();
            }
            
            levelVO.setTips(entry.getValue().stream().filter(l->{
                if (l.getRiskLevel() == 1){
                    return true;
                }else {
                    return false;
                }
            }).collect(Collectors.toList()).size());
            levelVO.setCommonly(entry.getValue().stream().filter(l->{
                if (l.getRiskLevel() == 2){
                    return true;
                }else {
                    return false;
                }
            }).collect(Collectors.toList()).size());
            levelVO.setMore(entry.getValue().stream().filter(l->{
                if (l.getRiskLevel() == 3){
                    return true;
                }else {
                    return false;
                }
            }).collect(Collectors.toList()).size());
            
            levelVO.setSerious(entry.getValue().stream().filter(l->{
                if (l.getRiskLevel() == 4){
                    return true;
                }else {
                    return false;
                }
            }).collect(Collectors.toList()).size());
            
            lists.add(levelVO);
        }
        lists = lists.stream().sorted(Comparator.comparing(RiskHomePageLevelVO::getTime)).collect(Collectors.toList());
        return lists;
    }
    
    @Override
    public HomePageRiskRespVO homePageRisk(HomePageRiskReqVO vo ){
        HomePageRiskRespVO respVO = new HomePageRiskRespVO();
        
        RiskMonitor monitor = new RiskMonitor();
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        if (vo.getSchemeId()!=0){
            monitor.setSchemeId(vo.getSchemeId());
        }
        
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        monitor.setCreateUserId(loginUser.getId());
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        List<Long> compIds = monitorService.queryList(monitor).stream().map(m -> m.getCompId())
                .collect(Collectors.toList());
        CompDept dept = new CompDept();
        dept.setDeptId(loginUser.getDeptId());
        List<Long> compId = compDeptService.queryList(dept).stream().map(d -> d.getCompId())
                .collect(Collectors.toList());
        
        compIds.addAll(compId);
        respVO.setCountComp(new Long(compIds.size()));//统计监控公司数量
        if (compIds.isEmpty()){
            respVO.setCountRisk(new BigDecimal(0));
            respVO.setJudicial(new BigDecimal(0));
            respVO.setBusiness(new BigDecimal(0));
            respVO.setManagement(new BigDecimal(0));
            respVO.setJudicialRatio("0.0");
            respVO.setBusinessRatio("0.0");
            respVO.setManagementRatio("0.0");
            respVO.setPrompt(new BigDecimal(0));
            respVO.setPromptRatio("0.0");
            respVO.setGeneral(new BigDecimal(0));
            respVO.setGeneralRatio("0.0");
            respVO.setLarger(new BigDecimal(0));
            respVO.setLargerRatio("0.0");
            respVO.setSevere(new BigDecimal(0));
            respVO.setSevereRatio("0.0");
            return respVO;
        }
        RiskDTO dto = new RiskDTO();
        String[] time = time(vo.getTimeType(), vo.getStartTime(), vo.getEndTime());
        dto.setStartTime(time[0]);
        dto.setEndTime(time[1]);
        dto.setCompIds(compIds);
        BigDecimal judicialAll = riskTypeService.countJudicialAll(dto);
        BigDecimal businessAll = riskTypeService.countBusinessAll(dto);
        BigDecimal managementAll = riskTypeService.countManagementAll(dto);
        respVO.setJudicial(judicialAll);
        respVO.setBusiness(businessAll);
        respVO.setManagement(managementAll);
        BigDecimal count = riskTypeService.countAllRisk(dto);
        respVO.setCountRisk(count);
        List<RiskTypeDTO> riskTypeDTOS = riskTypeService.countRiskType(dto);
        riskTypeDTOS.forEach(r->{
            r.setRatio(compute(r.getCount(),count));
        });
        if (riskTypeDTOS.size()>12){
            riskTypeDTOS = riskTypeDTOS.subList(0, 12);
        }
        respVO.setRiskTypeDTOS(riskTypeDTOS);
        respVO.setBusinessRatio(compute(businessAll,count));
        respVO.setJudicialRatio(compute(judicialAll,count));
        respVO.setManagementRatio(compute(managementAll,count));
        BigDecimal prompt = riskTypeService.countPrompt(dto);
        respVO.setPrompt(prompt);
        BigDecimal general = riskTypeService.countGeneral(dto);
        respVO.setGeneral(general);
        BigDecimal larger = riskTypeService.countLarger(dto);
        respVO.setLarger(larger);
        BigDecimal severe = riskTypeService.countSevere(dto);
        respVO.setSevere(severe);
        BigDecimal countLevel = riskTypeService.countLevel(dto);
        respVO.setPromptRatio(compute(prompt,countLevel));
        respVO.setGeneralRatio(compute(general,countLevel));
        respVO.setLargerRatio(compute(larger,countLevel));
        respVO.setSevereRatio(compute(severe,countLevel));
        return respVO;
    }
    
    
    
    
    @Override
    public RiskTrendVO homePageTrend(RiskHomePageReqVO vo){
        RiskMonitor monitor = new RiskMonitor();
        if (vo.getSchemeId() != 0) {
            monitor.setSchemeId(vo.getSchemeId());
        }
        RiskTrendVO riskTrendVO = new RiskTrendVO();
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        List<HomePageTrendVO> trendVOS = new ArrayList<>();
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        monitor.setCreateUserId(loginUser.getId());
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        List<Long> compIds = monitorService.queryList(monitor).stream().map(m -> m.getCompId())
                .collect(Collectors.toList());
        CompDept dept = new CompDept();
        dept.setDeptId(loginUser.getDeptId());
        compIds.addAll(compDeptService.queryList(dept).stream().map(d->d.getCompId()).collect(Collectors.toList()));
        if (compIds.isEmpty()){
            return riskTrendVO;
        }
        RiskDTO dto = new RiskDTO();
        String[] time = time(vo.getTimeType(), vo.getStartTime(), vo.getEndTime());
        dto.setStartTime(time[0]);
        dto.setEndTime(time[1]);
        dto.setCompIds(compIds);
        dto.setRiskTypes(riskTypeService.countRiskType(dto).stream().map(r->r.getRiskType()).collect(Collectors.toList()));
        RiskTimeDTO timeDTO = new RiskTimeDTO();
        timeDTO.setIds(compIds);
        timeDTO.setStartTime(time[0]);
        timeDTO.setEndTime(time[1]);
        List<RiskTypeDTO> typeDTOS = riskTypeService.queryListRisk(dto);

        Map<String,Map<String,Integer>> map = new HashMap<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        for (RiskTypeDTO t : typeDTOS) {
            if (null != t) {
                if (null != t.getTime()) {
                    String key = format.format(t.getTime());
                    Map<String, Integer> stringLongMap = map.get(key);
    
                    if (stringLongMap == null) {
                        Map<String, Integer> m = new HashMap<>();
                        if (t.getRiskType() != null) {
                            m.put(t.getRiskType(), 1);
                            map.put(key, m);
                        }
        
                    } else {
                        if (null != t.getRiskType()) {
                            if (null == stringLongMap.get(t.getRiskType())) {
                                stringLongMap.put(t.getRiskType(), 1);
                            } else {
                                stringLongMap.put(t.getRiskType(), stringLongMap.get(t.getRiskType()) + 1);
                            }
    
                        }
                    }
                }
            }
        }
    
        for (Map.Entry<String, Map<String, Integer>> entry : map.entrySet()) {
            HomePageTrendVO trendVO = new HomePageTrendVO();
            try {
                if (entry.getKey() != null) {
                    trendVO.setTime(format.parse(entry.getKey()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            trendVO.setRiskType(entry.getValue());
            trendVOS.add(trendVO);
        }
        
        riskTrendVO.setTypes(trendVOS);
        riskTrendVO.setRiskType(typeDTOS.stream().map(t->t.getRiskType()).distinct().collect(Collectors.toList()));
        
        
        return riskTrendVO;
    }
    
    
   public List<HomePageNewsTrendVO> homePageNewsTrend(RiskHomePageReqVO vo){
        RiskMonitor monitor = new RiskMonitor();
        if (!vo.getSchemeId().equals(0L)){
            monitor.setSchemeId(vo.getSchemeId());
        }
       User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        monitor.setCreateUserId(loginUser.getId());
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
       List<String> compIds = monitorService.queryList(monitor).stream()
               .map(c -> c.getCompId().toString()).collect(Collectors.toList());
       CompDept dept = new CompDept();
       dept.setDeptId(loginUser.getDeptId());
       List<String> compId = compDeptService.queryList(dept).stream().map(c -> c.getCompId().toString())
               .collect(Collectors.toList());
       compIds.addAll(compId);
       if (compIds.isEmpty()){
           return new ArrayList<>();
       }
       
       String[] time = time(vo.getTimeType(), vo.getStartTime(), vo.getEndTime());
       ListRiskNewsReqDTO dto = new ListRiskNewsReqDTO();
       dto.setCompIds(compIds);
       dto.setStart(time[0]);
       dto.setEnd(time[1]);
       List<AppNews> appNews = newsService.queryBySome(dto);
       SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
       Map<String,List<AppNews>> map = new HashMap<>();
       appNews.forEach(news->{
           String key = format.format(news.getPublishTime());
           List<AppNews> list = map.get(key);
           if (list==null){
                list = new ArrayList<>();
                list.add(news);
                map.put(key,list);
           }else {
               list.add(news);
           }
       });
    
       List<HomePageNewsTrendVO> list = new ArrayList<>();
       
       for (Map.Entry<String, List<AppNews>> entry : map.entrySet()) {
           HomePageNewsTrendVO trendVO = new HomePageNewsTrendVO();
           try {
               trendVO.setTime(format.parse(entry.getKey()));
           }catch (Exception e){
               e.printStackTrace();
           }
           
           trendVO.setPositive(entry.getValue().stream().filter(news->{
               if (Constant.SENTIMENT_POSITIVE.equals(news.getSentiment())){
                   return true;
               }else {
                   return false;
               }
           }).collect(Collectors.toList()).size());
           
           trendVO.setNeutral(entry.getValue().stream().filter(news->{
               if (Constant.SENTIMENT_NEUTRAL.equals(news.getSentiment())){
                   return true;
               }else {
                   return false;
               }
           }).collect(Collectors.toList()).size());
           
           trendVO.setNegative(entry.getValue().stream().filter(news->{
               if (Constant.SENTIMENT_NEGATIVE.equals(news.getSentiment())){
                   return true;
               }else {
                   return false;
               }
           }).collect(Collectors.toList()).size());
           
           list.add(trendVO);
       }
       list = list.stream().sorted((a,b)-> 0-a.getTime().compareTo(b.getTime())).collect(Collectors.toList());
       return list;
    }
    
    @Override
    public HomePageNewsRespVO homePageNews(RiskHomePageReqVO vo){
        HomePageNewsRespVO respVO =new HomePageNewsRespVO();
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        RiskPageNewsReqVO dto = new RiskPageNewsReqVO();
        RiskMonitor monitor = new RiskMonitor();
        monitor.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        if (vo.getSchemeId() != 0 && null != vo.getSchemeId()){
            monitor.setSchemeId(vo.getSchemeId());
        }
        monitor.setCreateUserId(loginUser.getId());
        List<String> compIds = monitorService.queryList(monitor).stream()
                .map(c -> c.getCompId().toString()).collect(Collectors.toList());
        CompDept dept = new CompDept();
        dept.setDeptId(loginUser.getDeptId());
        List<String> compId = compDeptService.queryList(dept).stream().map(c -> c.getCompId().toString())
                .collect(Collectors.toList());
        compIds.addAll(compId);
        respVO.setCountComp(new Integer(compIds.size()).longValue());
        if (compIds.isEmpty()){
            respVO.setNegativeRatio("0");
            respVO.setNegative(new BigDecimal(0));
            respVO.setNeutralRatio("0");
            respVO.setNeutral(new BigDecimal(0));
            respVO.setPositive(new BigDecimal(0));
            respVO.setPositiveRatio("0");
            respVO.setCountAll(new BigDecimal(0));
            return respVO;
        }
        if (null!=vo.getCompId()){
            if (compIds.contains(vo.getCompId())){
                compIds = Collections.singletonList(vo.getCompId().toString());
            }else {
                respVO.setNegativeRatio("0");
                respVO.setNegative(new BigDecimal(0));
                respVO.setNeutralRatio("0");
                respVO.setNeutral(new BigDecimal(0));
                respVO.setPositive(new BigDecimal(0));
                respVO.setPositiveRatio("0");
                respVO.setCountAll(new BigDecimal(0));
                return respVO;
            }
        }
        dto.setCompIds(compIds);
        String beginTime = null;
        String endTime = null;
        if (Constant.COMP_RISK_TIME_DAY.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.date(), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_WEEK.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -6), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), 0), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_MONTH.equals(vo.getTimeType())) {
            beginTime = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -1), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(),0 ), DatePattern.NORM_DATE_PATTERN)+" 23:59:59";
        } else if (Constant.COMP_RISK_TIME_DEFINE.equals(vo.getTimeType())) {
            if (null == vo.getStartTime() || null == vo.getEndTime()) {
                throw new ElkException(ElkErrorType.ELK_SEARCH_DATE_NULL);
            }
            beginTime = DateUtil.format(vo.getStartTime(), DatePattern.NORM_DATE_PATTERN);
            endTime = DateUtils.format(vo.getEndTime(),DateUtils.DATE)+" 23:59:59";
        }
        dto.setEndTime(endTime);
        dto.setStartTime(beginTime);
        
        
        respVO.setNewsSource(newsService.countSource(dto));
        respVO.setComps(appNewsSentimentService.countComp(dto));
        BigDecimal negative = appNewsSentimentService.countNegative(dto);
        respVO.setNegative(negative);//消极
        BigDecimal neutral = appNewsSentimentService.countNeutral(dto);
        respVO.setNeutral(neutral);//中立
        BigDecimal positive = appNewsSentimentService.countPositive(dto);
        respVO.setPositive(positive);//积极
        BigDecimal countAll = negative.add(neutral).add(positive);
        respVO.setCountAll(countAll);
        respVO.setNegativeRatio(compute(negative,countAll));
        
        respVO.setNeutralRatio(compute(neutral,countAll));
        respVO.setPositiveRatio(compute(positive,countAll));
        return respVO;
    }
    
    private String compute(BigDecimal bigDecimal,BigDecimal count){
        if (bigDecimal.equals(new BigDecimal(0)) || count.equals(new BigDecimal(0))){
            return "0.00";
        }
        BigDecimal multiply = new BigDecimal(100);
        BigDecimal one = new BigDecimal(1);
        BigDecimal divide = bigDecimal.divide(count, Constant.RETAIN_DECIMAL_DIGIT_FOUR, RoundingMode.HALF_UP).multiply(multiply);
        BigDecimal decimal = divide.divide(one, Constant.RETAIN_DECIMAL_DIGIT_TWO, RoundingMode.HALF_UP);
        return decimal+"";
    }
    
    
    public PageResult<ListNewsRespVO> listRiskNews(ReqDTO<ListRiskNewsReqVO> reqDTO){
        List<String> compIds = new ArrayList<>();
        PageResult<ListNewsRespVO> pageResult = new PageResult<>();
        List<Integer> sentiments = new ArrayList<>();
        List<Integer> sentimentsConf = new ArrayList<>();
        ListRiskNewsReqDTO dto = new ListRiskNewsReqDTO();
        if(null != reqDTO.getContent().getTitle() && !reqDTO.getContent().getTitle().isEmpty()){
            dto.setTitle("%"+reqDTO.getContent().getTitle()+"%");
            dto.setContent("%"+reqDTO.getContent().getTitle()+"%");
        }
        dto.setStart(reqDTO.getContent().getStartTime());
        dto.setEnd(reqDTO.getContent().getEndTime());
        sentiments.addAll(reqDTO.getContent().getSentiments());
        PageResult<AppNews> page;
        if(reqDTO.getContent().getSchemeIds().isEmpty()){
            dto.setSentiments(sentiments);
            page =  pageService.page(reqDTO.getPageParam(),()->newsService.query(dto));
            page.getRows().forEach(a->{
                if(null != reqDTO.getContent().getTitle() && !reqDTO.getContent().getTitle().isEmpty()){
                    String shortContent = this.getShortContent(a.getContent(), reqDTO.getContent().getTitle());
                    a.setContent(shortContent);
                }
            });
        }else{
            if (reqDTO.getContent().getSchemeIds().get(Constant.DEFAULT_STATUS_NORMAL) == 0) {
                User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
                RiskMonitor m = new RiskMonitor();
                m.setStatus(Constant.DEFAULT_STATUS_NORMAL);
                m.setCreateUserId(loginUser.getId());
                compIds.addAll(monitorService.queryList(m).stream().map(r -> r.getCompId().toString()).collect(Collectors.toList()));
                CompDept dept = new CompDept();
                dept.setDeptId(loginUser.getDeptId());
                compIds.addAll(compDeptService.queryList(dept).stream().map(c -> c.getCompId().toString()).collect(Collectors.toList()));
                if (compIds.isEmpty()) {
                    return pageResult;
                }
            }else {
                for (Long schemeId : reqDTO.getContent().getSchemeIds()) {
                    RiskMonitor m = new RiskMonitor();
                    m.setStatus(Constant.DEFAULT_STATUS_NORMAL);
                    m.setSchemeId(schemeId);
                    RiskSchemeConfig config = new RiskSchemeConfig();
                    config.setTagClass(Constant.RISK_SCHEME_CONFIG_MONITORING);
                    config.setSchemeId(schemeId);
                    sentimentsConf.addAll(configService.queryList(config).stream().map(c->c.getTagId().intValue()).collect(Collectors.toList()));
                    compIds.addAll(monitorService.queryList(m).stream().map(monitor->monitor.getCompId().toString()).collect(Collectors.toList()));
                }
            }
            dto.setCompIds(compIds);
            dto.setSentiments(sentiments);
            dto.setSentimentsConf(sentimentsConf);
            page = pageService.page(reqDTO.getPageParam(), () -> newsService.queryBySentiments(dto));
            page.getRows().forEach(a->{
                if(null != reqDTO.getContent().getTitle() && !reqDTO.getContent().getTitle().isEmpty()){
                    String shortContent = this.getShortContent(a.getContent(), reqDTO.getContent().getTitle());
                    a.setContent(shortContent);
                }
            });
        }
    
        
        List<ListNewsRespVO> news = new ArrayList<>();
        for (AppNews appNews :page.getRows()){
            ListNewsRespVO respDTO = new ListNewsRespVO();
            BeanUtils.copyProperties(appNews,respDTO);
            if ( null != respDTO.getHtml() && respDTO.getHtml() != ""){
                respDTO.setHtml(HtmlUtils.replaceHtmlTag(respDTO.getHtml(),minioAddress));
            }
            TagRel tagRel = new TagRel();
            tagRel.setDataType(Constant.TAG_DATATYPE_NEWS);
            tagRel.setDataId(appNews.getId());
            List<TagRel> tagRels = tagRelService.queryList(tagRel);
            AppNewsSentiment sentiment = new AppNewsSentiment();
            sentiment.setNewsId(appNews.getId());
            List<AppNewsSentiment> appNewsSentiments = appNewsSentimentService.queryList(sentiment);
            
            
            respDTO.setLabels(tagRels);
    
            List<QuerySentimentByNewsIdDTO> dtos = appNewsSentimentService
                    .querySentimentByNewsId(appNews.getId());
            if (dtos.size() >10 ){
                dtos = dtos.subList(0,10);
            }
            respDTO.setCompNames(dtos);
        
            if(null != appNews.getSentiment()){
                if (Constant.SENTIMENT_POSITIVE.equals(appNews.getSentiment())) {
                    respDTO.setSentiment("积极");
                }
                if (Constant.SENTIMENT_NEUTRAL.equals(appNews.getSentiment())) {
                    respDTO.setSentiment("中立");
                }
                if (Constant.SENTIMENT_NEGATIVE.equals(appNews.getSentiment())) {
                    respDTO.setSentiment("消极");
                }
            }
            news.add(respDTO);
        }
        List<ListNewsRespVO> collect = news.stream().distinct().sorted((a,b)->0-a.getPublishTime().compareTo(b.getPublishTime())).collect(Collectors.toList());
    
        pageResult.setRows(collect);
        pageResult.setPage(page.getPage());
        return pageResult;
    }
    
    private String getShortContent(String content,String keyWords){
        if(StringUtil.isBlank(content)){
            return null;
        }
        int length = content.length();
        if(StringUtil.isBlank(keyWords)){
            if(length>=300){
                return content.substring(0,300).trim();
            }
            return content;
        }
        
        String result = null;
        Matcher matcher = Pattern.compile(keyWords).matcher(content);
        if (matcher.find()) {
            int start = matcher.start();
            if(start>30){
                int sublength = length-start-30;
                if(sublength>=300){
                    result = content.substring(start-30,start+270).trim();
                }else{
                    result = content.substring(start-30).trim();
                }
            }else{
                if(length>=300){
                    result = content.substring(0,300);
                }else{
                    result = content;
                }
            }
        } else {
            if(length>=300){
                result = content.substring(0,300).trim();
            }else{
                result = content;
            }
        }
        return result;
    }
    
    
}
